﻿using UnityEngine;
using System.Collections;
using UniLua;

namespace TCG.FFI
{
	public static class UnityQuaternionLib
	{
		public static string LIB_NAME = "UnityQuaternionLib";

		public static Quaternion identity = Quaternion.identity;

		public static int lf_GetIdentity (ILuaState luaState)
		{
			LuaTools.L_PushUserData (luaState, identity, LIB_NAME);
			return 1;
		}

		public static int lf_Angle (ILuaState luaState)
		{
			Quaternion a = (Quaternion)LuaTools.L_CheckUData (luaState, 1, LIB_NAME);
			Quaternion b = (Quaternion)LuaTools.L_CheckUData (luaState, 2, LIB_NAME);
			luaState.PushNumber (Quaternion.Angle (a, b));
			return 1;
		}

		public static int lf_AngleAxis (ILuaState luaState)
		{
			float angle = (float)luaState.ToNumber (1);
			Vector3 axis = (Vector3)LuaTools.L_CheckUData (luaState, 2, UnityVector3Lib.LIB_NAME);
			LuaTools.L_PushUserData (luaState, Quaternion.AngleAxis (angle, axis), LIB_NAME);
			return 1;
		}

		public static int lf_Dot (ILuaState LuaState)
		{
			Quaternion a = (Quaternion)LuaTools.L_CheckUData (LuaState, 1, LIB_NAME);
			Quaternion b = (Quaternion)LuaTools.L_CheckUData (LuaState, 2, LIB_NAME);
			LuaState.PushNumber (Quaternion.Dot (a, b));
			return 1;
		}

		public static int lf_Euler (ILuaState luaState)
		{
			Vector3 euler = (Vector3)LuaTools.L_CheckUData (luaState, 1, LIB_NAME);
			LuaTools.L_PushUserData (luaState, Quaternion.Euler (euler), LIB_NAME);
			return 1;
		}

		public static int lf_FromToRotation (ILuaState luaState)
		{
			Vector3 fromDirection = (Vector3)LuaTools.L_CheckUData (luaState, 1, UnityVector3Lib.LIB_NAME);
			Vector3 toDirection = (Vector3)LuaTools.L_CheckUData (luaState, 2, UnityVector3Lib.LIB_NAME);
			LuaTools.L_PushUserData (luaState, Quaternion.FromToRotation (fromDirection, toDirection), LIB_NAME);
			return 1;
		}

		public static int lf_Inverse (ILuaState luaState)
		{
			Quaternion rotation = (Quaternion)LuaTools.L_CheckUData (luaState, 1, LIB_NAME);
			LuaTools.L_PushUserData (luaState, Quaternion.Inverse (rotation), LIB_NAME);
			return 1;
		}

		public static int lf_Lerp (ILuaState luaState)
		{
			Quaternion from = (Quaternion)LuaTools.L_CheckUData (luaState, 1, LIB_NAME);
			Quaternion to = (Quaternion)LuaTools.L_CheckUData (luaState, 2, LIB_NAME);
			float t = (float)luaState.ToNumber (3);
			LuaTools.L_PushUserData (luaState, Quaternion.Lerp (from, to, t), LIB_NAME);
			return 1;
		}

		public static int lf_LookRoration (ILuaState luaState)
		{
			Vector3 forward = (Vector3)LuaTools.L_CheckUData (luaState, 1, UnityVector3Lib.LIB_NAME);
			if (luaState.GetTop () == 1)
			{
				LuaTools.L_PushUserData (luaState, Quaternion.LookRotation (forward), LIB_NAME);
			}
			else
			{
				Vector3 upwards = (Vector3)LuaTools.L_CheckUData (luaState, 2, UnityVector3Lib.LIB_NAME);
				LuaTools.L_PushUserData (luaState, Quaternion.LookRotation (forward, upwards), LIB_NAME);
			}

			return 1;
		}

		public static int lf_RotateTowards (ILuaState luaState)
		{
			Quaternion from = (Quaternion)LuaTools.L_CheckUData (luaState, 1, LIB_NAME);
			Quaternion to = (Quaternion)LuaTools.L_CheckUData (luaState, 2, LIB_NAME);
			float maxDegreesDelta = (float)luaState.ToNumber (3);
			LuaTools.L_PushUserData (luaState, Quaternion.RotateTowards (from, to, maxDegreesDelta), LIB_NAME);
			return 0;
		}

		public static int lf_Slerp (ILuaState luaState)
		{
			Quaternion from = (Quaternion)LuaTools.L_CheckUData (luaState, 1, LIB_NAME);
			Quaternion to = (Quaternion)LuaTools.L_CheckUData (luaState, 2, LIB_NAME);
			float t = (float)luaState.ToNumber (3);
			LuaTools.L_PushUserData (luaState, Quaternion.Slerp (from, to, t), LIB_NAME);
			return 1;
		}

		public static int mf_GetEulerAngles (ILuaState luaState)
		{
			Quaternion quaternion = (Quaternion)LuaTools.L_CheckUData (luaState, 1, LIB_NAME);
			LuaTools.L_PushUserData (luaState, quaternion.eulerAngles, UnityVector3Lib.LIB_NAME);
			return 1;
		}

		public static int mf_SetEulerAngles (ILuaState luaState)
		{
			Quaternion quaternion = (Quaternion)LuaTools.L_CheckUData (luaState, 1, LIB_NAME);
			Vector3 angles = (Vector3)LuaTools.L_CheckUData (luaState, 2, UnityVector3Lib.LIB_NAME);
			quaternion.eulerAngles = angles;
			LuaTools.L_PushUserData (luaState, quaternion, LIB_NAME);
			return 1;
		}

		public static int mf_SetFromRotation (ILuaState luaState)
		{
			Quaternion quaternion = (Quaternion)LuaTools.L_CheckUData (luaState, 1, LIB_NAME);
			Vector3 fromDirection = (Vector3)LuaTools.L_CheckUData (luaState, 2, UnityVector3Lib.LIB_NAME);
			Vector3 toDirecition = (Vector3)LuaTools.L_CheckUData (luaState, 3, UnityVector3Lib.LIB_NAME);
			quaternion.SetFromToRotation (fromDirection, toDirecition);
			LuaTools.L_PushUserData (luaState, quaternion, LIB_NAME);
			return 1;
		}

		public static int mf_SetLookRoration (ILuaState luaState)
		{
			Quaternion quaternion = (Quaternion)LuaTools.L_CheckUData (luaState, 1, LIB_NAME);
			Vector3 view = (Vector3)LuaTools.L_CheckUData (luaState, 2, UnityVector3Lib.LIB_NAME);
			Vector3 up = Vector3.up;
			if (luaState.GetTop () > 2)
			{
				up = (Vector3)LuaTools.L_CheckUData (luaState, 3, UnityVector3Lib.LIB_NAME);
			}
			quaternion.SetLookRotation (view, up);
			LuaTools.L_PushUserData (luaState, quaternion, LIB_NAME);
			return 1;
		}

		public static int mf_ToAngleAxis (ILuaState luaState)
		{
			Quaternion quaternion = (Quaternion)LuaTools.L_CheckUData (luaState, 1, LIB_NAME);
			float angle = 0;
			Vector3 axis = Vector3.zero;
			quaternion.ToAngleAxis (out angle, out axis);
			luaState.PushNumber (angle);
			LuaTools.L_PushUserData (luaState, axis, UnityVector3Lib.LIB_NAME);
			return 2;
		}


	};
	
}
